const express = require('express');
const router = express.Router();
const pool = require('./db.js');
const UNAUTHORIZED_MODIFICATION_MSG = '无权修改该用户信息';
const NOT_LOGGED_IN_MSG = '用户未登录';
const DIFFERENT_DEVICE_MSG = '该用户已在其他设备登录，此会话失效';
const crypto = require('crypto');
const { encryptForUser, decryptForUser } = require('./userDataEncryption.js');

// 生成唯一的设备令牌
function generateDeviceToken() {
    return crypto.randomBytes(16).toString('hex');
}

// 生成数据哈希
function generateDataHash(data) {
    if (!data) return null;
    return crypto.createHash('sha256').update(data).digest('hex');
}

// 注册接口
router.post('/register', async (req, res) => {
    const { userId, username, email, password, name, student_id, role } = req.body;
    
    try {
        // 1. 检查用户ID是否存在
        const [userIdRows] = await pool.execute('SELECT * FROM users WHERE user_id =?', [userId]);
        if (userIdRows.length > 0) {
            return res.json({ message: '用户ID已被使用' });
        }
        
        // 2. 检查用户名哈希是否唯一
        const usernameHash = generateDataHash(username);
        const [hashRows] = await pool.execute('SELECT * FROM users WHERE username_hash =?', [usernameHash]);
        if (hashRows.length > 0) {
            return res.json({ message: '用户名已存在' });
        }
        
        // 3. 检查学号哈希是否唯一
        if (student_id) {
            const studentIdHash = generateDataHash(student_id);
            const [studentIdRows] = await pool.execute('SELECT * FROM users WHERE student_id_hash =?', [studentIdHash]);
            if (studentIdRows.length > 0) {
                return res.json({ message: '学号已被使用' });
            }
        }
        
        // 4. 加密敏感字段
        const encryptedUsername = encryptForUser(userId, username);
        const encryptedEmail = encryptForUser(userId, email);
        const encryptedPassword = encryptForUser(userId, password);
        const encryptedName = name ? encryptForUser(userId, name) : '';
        const encryptedStudentId = student_id ? encryptForUser(userId, student_id) : '';
        const studentIdHash = student_id ? generateDataHash(student_id) : null;
        
        // 5. 插入加密后的数据
        await pool.execute(
            'INSERT INTO users (user_id, username, username_hash, email, password, name, student_id, student_id_hash, role, is_logged_in, device_id) VALUES (?,?,?,?,?,?,?,?,?,?, NULL)',
            [
                userId,
                encryptedUsername,
                usernameHash,
                encryptedEmail,
                encryptedPassword,
                encryptedName,
                encryptedStudentId,
                studentIdHash,
                role,
                false
            ]
        );
        
        res.json({ message: '注册成功' });
    } catch (error) {
        console.error('注册失败:', error);
        
        if (error.message.includes('Data too long') || error.message.includes('truncated')) {
            return res.status(400).json({ 
                message: '数据长度超出限制',
                suggestion: '请使用较短的输入值'
            });
        }
        
        res.status(500).json({ message: '服务器错误' });
    }
});

// 检查 user_id 是否存在
router.get('/check-user-id', async (req, res) => {
    const { userId } = req.query;
    try {
        const [rows] = await pool.execute('SELECT * FROM users WHERE user_id =?', [userId]);
        res.json({ exists: rows.length > 0 });
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 检查学号是否存在
router.get('/check-student-id', async (req, res) => {
    const { studentId } = req.query;
    
    if (!studentId) {
        return res.status(400).json({ 
            success: false, 
            message: '请提供学号' 
        });
    }
    
    try {
        const studentIdHash = generateDataHash(studentId);
        const [rows] = await pool.execute(
            'SELECT user_id FROM users WHERE student_id_hash = ?',
            [studentIdHash]
        );
        
        const exists = rows.length > 0;
        
        res.json({ 
            success: true,
            exists: exists
        });
    } catch (error) {
        console.error('查询学号失败:', error);
        res.status(500).json({ 
            success: false,
            message: '服务器错误',
            error: error.message
        });
    }
});

// 登录接口
router.post('/login', async (req, res) => {
    const { username, password } = req.body;
    const deviceToken = generateDeviceToken(); 
    
    try {
        // 1. 使用用户名哈希查询用户
        const usernameHash = generateDataHash(username);
        const [userRows] = await pool.execute('SELECT * FROM users WHERE username_hash =?', [usernameHash]);
        
        if (userRows.length === 0) {
            return res.json({ message: '用户名或密码错误' });
        }
        
        const user = userRows[0];
        
        // 2. 解密密码字段
        const decryptedPassword = decryptForUser(user.user_id, user.password);
        
        // 3. 验证密码
        if (decryptedPassword !== password) {
            return res.json({ message: '用户名或密码错误' });
        }
        
        // 4. 更新登录状态
        await pool.execute('UPDATE users SET is_logged_in = TRUE, device_id =? WHERE user_id =?', 
                          [deviceToken, user.user_id]);
        
        // 5. 设置 session
        req.session.userId = user.user_id;
        req.session.device_id = deviceToken;
        
        res.json({ 
            message: '登录成功',
            userId: user.user_id
        });
    } catch (error) {
        console.error('登录失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 中间件：检查用户是否登录
const checkLoggedIn = (req, res, next) => {
    if (!req.session.userId) {
        return res.status(401).json({ message: NOT_LOGGED_IN_MSG });
    }
    
    try {
        pool.execute('SELECT device_id FROM users WHERE user_id =?', [req.session.userId])
        .then(([rows]) => {
            if (rows.length === 0) {
                req.session.destroy();
                return res.status(401).json({ message: '用户不存在' });
            }
            
            const userDeviceId = rows[0].device_id;
            const sessionDeviceId = req.session.device_id;
            
            if (userDeviceId !== sessionDeviceId) {
                req.session.destroy();
                return res.status(401).json({ message: DIFFERENT_DEVICE_MSG });
            }
            
            next();
        })
        .catch((error) => {
            console.error('中间件查询错误:', error);
            res.status(500).json({ message: '服务器错误' });
        });
    } catch (error) {
        console.error('验证用户登录状态失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
};

// 获取用户信息接口
router.get('/user-info', checkLoggedIn, async (req, res) => {
    try {
        const userId = req.session.userId;
        
        const [rows] = await pool.execute(
            'SELECT user_id, username, email, name, student_id, role FROM users WHERE user_id =?', 
            [userId]
        );
        
        if (rows.length === 0) {
            return res.status(404).json({ message: '用户未找到' });
        }
        
        const encryptedUser = rows[0];
        
        // 解密用户数据
        const decryptedUser = {
            user_id: encryptedUser.user_id,
            username: decryptForUser(userId, encryptedUser.username),
            email: decryptForUser(userId, encryptedUser.email),
            name: encryptedUser.name ? decryptForUser(userId, encryptedUser.name) : '',
            student_id: encryptedUser.student_id ? decryptForUser(userId, encryptedUser.student_id) : '',
            role: encryptedUser.role
        };
        
        res.json(decryptedUser);
    } catch (error) {
        console.error('获取用户信息失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 获取用户信息接口（传入ID版本） - 添加解密逻辑
router.get('/user-info-by-id', async (req, res) => {
    const { userId } = req.query;
    try {
        const [rows] = await pool.execute('SELECT name FROM users WHERE user_id =?', [userId]);
        if (rows.length > 0) {
            // 解密姓名
            const decryptedName = decryptForUser(userId, rows[0].name);
            res.json({ name: decryptedName });
        } else {
            res.status(404).json({ message: '用户未找到' });
        }
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 更新用户信息接口
router.post('/update-user-info', checkLoggedIn, async (req, res) => {
    const userId = req.session.userId;
    const { oldUsername, newUsername, name, student_id } = req.body;
    
    try {
        // 1. 验证当前用户
        const [userRows] = await pool.execute('SELECT username FROM users WHERE user_id =?', [userId]);
        if (userRows.length === 0) {
            return res.status(404).json({ message: '用户未找到' });
        }
        
        // 2. 解密当前用户名
        const currentUsername = decryptForUser(userId, userRows[0].username);
        if (currentUsername !== oldUsername) {
            return res.status(403).json({ message: UNAUTHORIZED_MODIFICATION_MSG });
        }
        
        // 3. 验证新用户名格式
        const usernameRegex = /^[a-zA-Z0-9]{3,10}$/;
        if (!usernameRegex.test(newUsername)) {
            return res.json({ message: '用户名不符合条件' });
        }
        
        // 4. 检查新用户名哈希是否唯一
        const newUsernameHash = generateDataHash(newUsername);
        const [checkRows] = await pool.execute(
            'SELECT * FROM users WHERE username_hash =? AND user_id !=?', 
            [newUsernameHash, userId]
        );
        
        if (checkRows.length > 0) {
            return res.json({ message: '该用户名已被使用' });
        }
        
        // 5. 检查新学号哈希是否唯一（如果提供了新学号）
        let studentIdHash = null;
        if (student_id) {
            studentIdHash = generateDataHash(student_id);
            const [studentIdRows] = await pool.execute(
                'SELECT * FROM users WHERE student_id_hash =? AND user_id !=?', 
                [studentIdHash, userId]
            );
            
            if (studentIdRows.length > 0) {
                return res.json({ message: '该学号已被使用' });
            }
        }
        
        // 6. 加密新数据
        const encryptedNewUsername = encryptForUser(userId, newUsername);
        const encryptedName = name ? encryptForUser(userId, name) : '';
        const encryptedStudentId = student_id ? encryptForUser(userId, student_id) : '';
        
        // 7. 更新数据库
        await pool.execute(
            'UPDATE users SET username =?, username_hash =?, name =?, student_id =?, student_id_hash =? WHERE user_id =?',
            [
                encryptedNewUsername,
                newUsernameHash,
                encryptedName,
                encryptedStudentId,
                studentIdHash,
                userId
            ]
        );
        
        res.json({ message: '信息保存成功' });
    } catch (error) {
        console.error('更新用户信息失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 修改密码接口
router.post('/change-password', checkLoggedIn, async (req, res) => {
    const userId = req.session.userId;
    const { oldPassword, newPassword } = req.body;
    
    try {
        // 1. 获取用户信息
        const [userRows] = await pool.execute(
            'SELECT password FROM users WHERE user_id =?', 
            [userId]
        );
        
        if (userRows.length === 0) {
            return res.status(404).json({ message: '用户未找到' });
        }
        
        // 2. 验证旧密码
        const decryptedPassword = decryptForUser(userId, userRows[0].password);
        if (decryptedPassword !== oldPassword) {
            return res.json({ message: '原密码不正确' });
        }
        
        // 3. 验证新密码格式
        const passwordRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,}$/;
        if (!passwordRegex.test(newPassword)) {
            return res.json({ message: '新密码不符合条件' });
        }
        
        if (oldPassword === newPassword) {
            return res.json({ message: '新密码不能与原密码一致' });
        }
        
        // 4. 加密并更新新密码
        const encryptedNewPassword = encryptForUser(userId, newPassword);
        await pool.execute(
            'UPDATE users SET password =? WHERE user_id =?', 
            [encryptedNewPassword, userId]
        );
        
        res.json({ message: '密码修改成功' });
    } catch (error) {
        console.error('修改密码失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 退出登录接口
router.post('/logout', checkLoggedIn, async (req, res) => {
    const userId = req.session.userId;
    
    try {
        await pool.execute(
            'UPDATE users SET is_logged_in = FALSE, device_id = NULL WHERE user_id =?', 
            [userId]
        );
        
        req.session.destroy((err) => {
            if (err) {
                console.error('销毁session失败:', err);
                return res.status(500).json({ message: '服务器错误' });
            }
            res.json({ message: '退出登录成功' });
            //console.log(`用户 ${userId} 退出登录`);
        });
    } catch (error) {
        console.error('退出登录失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 心跳检测接口
router.get('/heartbeat', checkLoggedIn, async (req, res) => {
    const userId = req.session.userId;
    
    try {
        const [rows] = await pool.execute(
            'SELECT is_logged_in, device_id FROM users WHERE user_id =?', 
            [userId]
        );
        
        if (rows.length === 0) {
            req.session.destroy();
            return res.status(401).json({ message: '用户不存在' });
        }
        
        const user = rows[0];
        if (user.is_logged_in && user.device_id === req.session.device_id) {
            res.json({ message: '心跳正常' });
        } else {
            req.session.destroy();
            res.status(401).json({ message: '会话已过期，请重新登录' });
        }
    } catch (error) {
        console.error('心跳检测失败:', error);
        res.status(500).json({ message: '服务器错误' });
    }
});

// 获取用户班级信息
router.get('/get-user-class', async (req, res) => {
    const { username } = req.query;
    
    try {
        // 通过用户名哈希查询用户ID
        const usernameHash = generateDataHash(username);
        const [userRows] = await pool.execute(
            'SELECT user_id FROM users WHERE username_hash =?', 
            [usernameHash]
        );
        
        if (userRows.length === 0) {
            return res.json({ class_code: null, message: '用户未找到' });
        }
        
        const userId = userRows[0].user_id;
        const [classRows] = await pool.execute(
            'SELECT class_code FROM class_attention WHERE user_id =?', 
            [userId]
        );
        
        if (classRows.length === 0) {
            return res.json({ class_code: null, message: '用户未加入班级' });
        }
        
        const classCode = classRows[0].class_code;
        const [classCodeRows] = await pool.execute(
            'SELECT class_name FROM classes WHERE class_code =?', 
            [classCode]
        );
        
        if (classCodeRows.length > 0) {
            return res.json({ 
                class_code: classCode,
                class_name: classCodeRows[0].class_name, 
                message: '成功获取班级信息' 
            });
        } else {
            return res.json({ class_code: null, message: '班级信息未找到' });
        }
    } catch (error) {
        console.error('获取用户班级失败:', error);
        return res.json({ class_code: null, message: '服务器错误' });
    }
});

// 检查用户名是否存在
router.get('/check-username', async (req, res) => {
    const { username } = req.query;
    
    if (!username) {
        return res.status(400).json({ 
            success: false, 
            message: '请提供用户名' 
        });
    }
    
    try {
        const usernameHash = generateDataHash(username);
        const [rows] = await pool.execute(
            'SELECT user_id FROM users WHERE username_hash = ?',
            [usernameHash]
        );
        
        const exists = rows.length > 0;
        
        res.json({ 
            success: true,
            exists: exists
        });
    } catch (error) {
        console.error('查询用户名失败:', error);
        res.status(500).json({ 
            success: false,
            message: '服务器错误',
            error: error.message
        });
    }
});

// 获取系统统计数据
router.get('/dashboard-stats', async (req, res) => {
    try {
        const [
            [courseCount],
            [resourceCount],
            [practiceCount],
            [userCount]
        ] = await Promise.all([
            pool.execute('SELECT COUNT(*) as count FROM courses'),
            pool.execute('SELECT COUNT(*) as count FROM resources'),
            pool.execute('SELECT COUNT(*) as count FROM practice'),
            pool.execute('SELECT COUNT(*) as count FROM users')
        ]);

        res.json({
            success: true,
            data: {
                courses: courseCount[0].count,
                resources: resourceCount[0].count,
                practices: practiceCount[0].count,
                users: userCount[0].count
            }
        });
    } catch (error) {
        console.error('获取统计数据失败:', error);
        res.status(500).json({
            success: false,
            message: '获取统计数据失败',
            error: error.message
        });
    }
});

router.get('/init-username-hashes', async (req, res) => {
    try {
        // 1. 获取所有用户数据
        const [users] = await pool.query('SELECT user_id, username FROM users');
        let successCount = 0;
        let errorCount = 0;
        const results = [];
        
        // 2. 遍历所有用户
        for (const user of users) {
            try {
                // 3. 解密用户名
                const decryptedUsername = decryptForUser(user.user_id, user.username);
                
                // 4. 计算用户名哈希
                const usernameHash = generateDataHash(decryptedUsername);
                
                // 5. 更新数据库
                await pool.execute(
                    'UPDATE users SET username_hash = ? WHERE user_id = ?',
                    [usernameHash, user.user_id]
                );
                
                successCount++;
                results.push({
                    userId: user.user_id,
                    originalUsername: user.username,
                    decryptedUsername,
                    usernameHash,
                    status: 'success'
                });
            } catch (error) {
                errorCount++;
                results.push({
                    userId: user.user_id,
                    originalUsername: user.username,
                    error: error.message,
                    status: 'failed'
                });
                console.error(`用户 ${user.user_id} 哈希初始化失败:`, error);
            }
        }
        
        // 6. 返回结果
        res.json({
            success: true,
            message: '用户名哈希初始化完成',
            totalUsers: users.length,
            successCount,
            errorCount,
            results
        });
    } catch (error) {
        console.error('初始化用户名哈希失败:', error);
        res.status(500).json({
            success: false,
            message: '初始化用户名哈希失败: ' + error.message
        });
    }
});

module.exports = router;